package yxy.cherry.data;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.redisson.api.RBucket;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import yxy.apple.util.FileUtility;
import yxy.apple.util.JSONUtility;
import yxy.apple.util.MD5Utility;
import yxy.apple.util.ReflectionUtility;
import yxy.apple.util.redisson.FastjsonCodec;
import yxy.apple.util.redisson.RedisConnection;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.bean.model.DataClass;
import yxy.cherry.data.input.Configuration;
import yxy.cherry.data.input.Version;


public class DataMakerAct {

	static String packageName = "yxy.cherry.data.bean";

	public void make() {
		try {
			File[] files = FileUtility.getFiles(System.getProperty("user.dir") + "/data/json/", ".json");
			for (File file : files) {
				makeFile(file, DataMaker.DIR, packageName);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	void makeFile(File file, String dir, String packageName) throws Exception {
	}

	
	public void start(Configuration configuration) throws Exception {
		// 启动配置 config

		// 获取redis连接，是否能连接
		RedisConnection redis = new RedisConnection();
		try {
			redis.connect(configuration.Redis.Address, configuration.Redis.Password, configuration.Redis.Database, true, new FastjsonCodec());
		} catch (RedisException e) {
			e.printStackTrace();
			System.err.println("Redis服务器连接错误");
			throw e;
		}
		RedissonClient client = redis.client();

		redisData(client, configuration, 0);// json

		redis.disconnect();
	}

	static String url = System.getProperty("user.dir") + "/data/";
	
//	private void redisData(RedissonClient client, int areaid, String url) throws Exception {
//		
//		Map<String, String> filesMD5 = new HashMap<>();
//		
//		File[] files = FileUtility.getFiles(url, ".json");
//		
//		for (File file : files) {
//			String md5 = null;
//			try {
//				md5 = MD5Utility.getMD5(file);
//			} catch (Exception e) {
//				e.printStackTrace();
//				System.err.println("md5解析错误：%s" + e.getMessage());
//				throw e;
//			}
//			// 检查内容
//			JSONArray dataArray = JSONUtility.readArray(file);
//			for (int i = 0; i < dataArray.size(); i++) {
//				JSONObject data = dataArray.getJSONObject(i);
//				if (!data.containsKey("id")) {
//					System.err.println("数据不存在id键值:%s" + file.getName());
//				}
//			}
//
//			filesMD5.put(file.getName(), md5);
//		}
//		
//		Version version = Version.defaultVersion;
//		RBucket<String> versionBucket = client.getBucket("ACT:DATA:" + areaid + ":VERSION");
//		if(versionBucket.isExists()) {
//			versionBucket.set(version.toString());			
//		}
//				
//		// 检查redis库是否有对应的文件md5的key 如果没有属于新建
//		String md5key = String.format("ACT:DATA:%s:%s:MD5", areaid, version);
//		RMap<String, String> rmap = client.getMap(md5key);
////		boolean isnew = !rmap.isExists();
//		
//		Set<Class<? extends DataClass>> dataTypeSet = ReflectionUtility.getSubTypesOf("yxy.cherry.data.bean", DataClass.class);
//		
//		Map<String, Class<? extends DataClass>> dataTypeMap = new HashMap<>();
//		for (Class<? extends DataClass> clazz : dataTypeSet) {
//			String name = clazz.getSimpleName();
//			if(!name.contains("act")) {
//				continue;
//			}
//			dataTypeMap.put(name, clazz);
//		}
//		
////		Map<String, Class<? extends DataClass>> datatypemap = new HashMap<>();
////		for (Class<? extends DataClass> clazz : dataTypeSet) {
////			String name = clazz.getSimpleName();
////			if(!name.contains("act")) {
////				continue;
////			}
////			dataTypeMap.put(name, clazz);
////		}
//		
//		// 逐个核对文件
//		for (File file : files) {
//			String filename = FileUtility.getFileNameWithoutExtension(file);// 文件名
//			if(!filename.contains("act")) {
//				continue;
//			}
//			
//			String name = file.getName();
//			String newmd5 = filesMD5.get(file.getName());
//			
//			if(!rmap.isExists()) {
//				rmap.put(name, newmd5);
//				saveRedisData(client, file, dataTypeMap, areaid, version);
//			}
//			
//			if(rmap.containsKey(name)) {
//				String oldmd5 = rmap.get(name);
//				if(newmd5.equals(oldmd5)) {
//					continue;
//				}
//				
//				String key = "ACT:DATA:" + areaid + ":" + version.toString() + ":DATAS:" + name;
////				client.
//			}
//		}
//	}
	
	private void saveRedisData(RedissonClient client, File file, Map<String, Class<? extends DataClass>> dataTypeMap, int areaid,
			Version version) throws Exception{
		String filename = FileUtility.getFileNameWithoutExtension(file);// 文件名
		if (dataTypeMap.containsKey(filename)) {
			System.err.println("put file ::" + filename);
			HashMap<String, DataClass> dataMap = new HashMap<>();
			Class<? extends DataClass> clazz = dataTypeMap.get(filename);
			JSONArray dataArray = JSONUtility.readArray(file);
			for (int i = 0; i < dataArray.size(); i++) {
				DataClass dc = dataArray.getObject(i, clazz);
				dataMap.put(dc.getCode(), dc);
			}
			client.getMap("ACT:DATA:" + areaid + ":" + version.toString() + ":DATAS:" + filename).putAll(dataMap);
			return;
		}

		HashMap<Integer, JSONObject> dataMap = new HashMap<>();
		JSONArray dataArray = JSONUtility.readArray(file);
		for (int i = 0; i < dataArray.size(); i++) {
			JSONObject data = dataArray.getJSONObject(i);
			int id = data.getIntValue("id");
			dataMap.put(id, data);
		}
		client.getMap("ACT:DATA:" + areaid + ":" + version.toString() + ":DATAS:" + filename).putAll(dataMap);
	
	}
	
	private void redisData(RedissonClient client, Configuration configuration, int areaid) throws Exception {
		// 获取文件，检查文件：md5校验，键值变化
		Map<String, String> filesMD5 = new HashMap<>();
		
//		int areaid = getAreaId();

		File[] files = FileUtility.getFiles(System.getProperty("user.dir") + "/data/", ".json");
		for (File file : files) {
			String md5 = null;
			try {
				md5 = MD5Utility.getMD5(file);
			} catch (Exception e) {
				e.printStackTrace();
				System.err.println("md5解析错误：%s" + e.getMessage());
				throw e;
			}
			// 检查内容
			JSONArray dataArray = JSONUtility.readArray(file);
			for (int i = 0; i < dataArray.size(); i++) {
				JSONObject data = dataArray.getJSONObject(i);
				if (!data.containsKey("id")) {
					System.err.println("数据不存在id键值:%s" + file.getName());
//					throw new Exception();
				}
			}

			filesMD5.put(file.getName(), md5);
		}

		Version version = Version.defaultVersion;
		String versionkey = String.format("ACT:DATA:%s:%s", areaid, version);
		RBucket<String> rbucket = client.getBucket(versionkey);
		if (rbucket.isExists()) {
			String versionString = rbucket.get();
			version = new Version(configuration.MajorVersion, versionString);
		}

		// 检查redis库是否有对应的文件md5的key 如果没有属于新建
		RMap<String, String> rmap = client.getMap("ACT:DATA:" + areaid + ":" + version.toString() + ":MD5");
		boolean isnew = !rmap.isExists();

		if (isnew) {
			rmap.putAll(filesMD5);
			
//			Set<Class<? extends DataClass>> dataTypeSet = ReflectionUtility.getSubTypesOf("yxy.game.pm2.active.data.bean", DataClass.class);
			Set<Class<? extends DataClass>> dataTypeSet = ReflectionUtility.getSubTypesOf("yxy.cherry.data.bean", DataClass.class);
			
			Map<String, Class<? extends DataClass>> dataTypeMap = new HashMap<>();
			for (Class<? extends DataClass> clazz : dataTypeSet) {
				String name = clazz.getSimpleName();
				if(!name.contains("act")) {
					continue;
				}
				dataTypeMap.put(name, clazz);
			}

			// 逐个存储文件
			for (File file : files) {
				String filename = FileUtility.getFileNameWithoutExtension(file);// 文件名
				if (dataTypeMap.containsKey(filename)) {
					System.err.println("put file ::" + filename);
					HashMap<String, DataClass> dataMap = new HashMap<>();
					Class<? extends DataClass> clazz = dataTypeMap.get(filename);
					JSONArray dataArray = JSONUtility.readArray(file);
					for (int i = 0; i < dataArray.size(); i++) {
						DataClass dc = dataArray.getObject(i, clazz);
						dataMap.put(dc.getCode(), dc);
					}
					client.getMap("ACT:DATA:" + areaid + ":" + version.toString() + ":DATAS:" + filename).putAll(dataMap);
					continue;
				}

				HashMap<Integer, JSONObject> dataMap = new HashMap<>();
				JSONArray dataArray = JSONUtility.readArray(file);
				for (int i = 0; i < dataArray.size(); i++) {
					JSONObject data = dataArray.getJSONObject(i);
					int id = data.getIntValue("id");
					dataMap.put(id, data);
				}
				client.getMap("ACT:DATA:" + areaid + ":" + version.toString() + ":DATAS:" + filename).putAll(dataMap);
			}
			RBucket<String> versionBucket = client.getBucket("ACT:DATA:" + areaid + ":VERSION");
			versionBucket.set(version.toString());
		}

		// 版本控制：如果数据表有增减，大版本号更新；如果部分表格结构有变化，中版本号更新；如果结构没有变化，只是数据变化，小版本号更新。

		// TODO: redis key常量化，版本号提升，java文件自动生成

	}
}
